define(["jquery", "jquery-ui"], function ($$, $) {
    "use strict";

    $.widget("custom.colorize", {
        // default options
        options: {
            red: 255,
            green: 0,
            blue: 0,

            // callbacks
            change: null,
            random: null
        },

        // the constructor
        _create: function () {
            this.element
                // add a class for theming
                .addClass("custom-colorize")
                // prevent double click to select text
                .disableSelection();

            this.changer = $("<button>", {
                text: "change",
                "class": "custom-colorize-changer"
            }).appendTo(this.element);

            // bind click events on the changer button to the random method
            this._on(this.changer, {
                // _on won't call random when widget is disabled
                click: "random"
            });
            this._refresh();
        },

        // called when created, and later when changing options
        _refresh: function () {
            this.element.css("background-color", "rgb(" +
                this.options.red + "," +
                this.options.green + "," +
                this.options.blue + ")"
            );

            // trigger a callback/event
            this._trigger("change");
        },

        // a public method to change the color to a random value
        // can be called directly via .colorize( "random" )
        random: function (event) {
            var colors = {
                red: Math.floor(Math.random() * 256),
                green: Math.floor(Math.random() * 256),
                blue: Math.floor(Math.random() * 256)
            };

            // trigger an event, check if it's canceled
            if (this._trigger("random", event, colors) !== false) {
                this.option(colors);
            }
        },

        // events bound via _on are removed automatically
        // revert other modifications here
        _destroy: function () {
            // remove generated elements
            this.changer.remove();

            this.element
                .removeClass("custom-colorize")
                .enableSelection()
                .css("background-color", "transparent");
        },

        // _setOptions is called with a hash of all options that are changing
        // always refresh when changing options
        _setOptions: function () {
            // _super and _superApply handle keeping the right this-context
            this._superApply(arguments);
            this._refresh();
        },

        // _setOption is called for each individual option that is changing
        _setOption: function (key, value) {
            // prevent invalid color values
            if (/red|green|blue/.test(key) && (value < 0 || value > 255)) {
                return;
            }
            this._super(key, value);
        }
    });

    return $;
});

